/**
 * Copyright (c) 2020 kedacom
 * OpenATC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 **/
package com.openatc.agent.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.openatc.agent.model.*;
import com.openatc.agent.realm.JwtToken;
import com.openatc.agent.service.*;
import com.openatc.agent.service.impl.WebOperationCollector;
import com.openatc.agent.service.impl.WebOperationRecordExtractor;
import com.openatc.agent.utils.TokenUtil;
import com.openatc.core.model.RESTRet;
import com.openatc.core.model.RESTRetBase;
import com.openatc.core.util.DateUtil;
import com.openatc.core.util.RESTRetUtils;
import com.openatc.extend.common.aop.model.SysLog;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.logging.Logger;

import static com.openatc.agent.model.TokenModel.LOGIN_SOURCE;
import static com.openatc.core.common.IErrorEnumImplOuter.*;


/**
 * @author kedacom
 * @ClassName: UserController
 * @Description:
 * @date 2019年10月19日 下午5:27:48
 */
//@Tag(name = "用户管理接口")
@RestController
@CrossOrigin
public class UserController {
    private static Logger logger = Logger.getLogger(UserController.class.toString());
    private static String STANDARD_DATE_FORMAT_UTC = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
    //    public volatile Map<String, Token> tokenMap = new HashMap<>();
    public long timestamp;
    @Autowired
    protected UserDao userDao;
    @Autowired
    protected PermissionDao permissionDao;
    @Autowired
    protected UserRoleDao userRoleDao;
    @Autowired
    protected RoleDao roleDao;
    @Autowired
    protected TokenUtil tokenUtil;

    @Autowired
    protected TokenDao tokenDao;
    @Value("${agent.lang.type:cn}")
    private String agentLangType;

    private Gson gson = new GsonBuilder().create();



    /**
     * 根据用户创建授权token
     */
//    @Operation(summary = "创建用户token")
    @PostMapping(value = "/auth/user/token")
    public RESTRetBase getTokenByUsername(@RequestBody JsonObject jsonObject) {
        String userName = jsonObject.get("user_name").getAsString();
        String endtime = jsonObject.get("end_time").getAsString();
        String starttime = jsonObject.get("start_time").getAsString();
        String description = jsonObject.get("description").getAsString();
        Date enddate = DateUtil.stringToDate(endtime);
        Date startdate = DateUtil.stringToDate(starttime);
        String token = tokenUtil.generateToken(userName, System.currentTimeMillis(),enddate,startdate);
        TokenModel tokenModel = new TokenModel();
        tokenModel.setToken(token);
        tokenModel.setStartTime(startdate);
        tokenModel.setEndTime(enddate);
        tokenModel.setDescription(description);
        tokenModel.setRelateUser(userName);
        tokenModel.setIsValid(true);
        tokenDao.save(tokenModel);
        // 更新token的缓存
        TokenUtil.updateTokenCache(tokenModel);
        Map resultmap = new HashMap();
        resultmap.put("token", token);
        return RESTRetUtils.successObj(resultmap);
    }

    /**
     * @return RESTRetBase
     * @Title: edgeLogin
     * @Description: com.app.name=openatc 有openatc表示平台版本, 需要配置shiro, 且ShiroOpenUtil的返回值为true
     */
    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @PostMapping(value = "/auth/login")
    public RESTRetBase edgeLogin(HttpServletRequest httpServletRequest, @RequestBody JsonObject loginUser) throws Exception {
        String userName = loginUser.get("user_name").getAsString();
        String password = loginUser.get("password").getAsString();
        timestamp = loginUser.get("timestamp").getAsLong();
        String remote = getRemoteIP(httpServletRequest);
        User user = userDao.getUserByUserName(userName);

        //不存在该用户
        if (user == null) {
            return RESTRetUtils.errorObj(E_3011);
        }

        //判断IP是否正确
        if ( ! checkip(remote, user.getLogin_ip_limit())) {
            return RESTRetUtils.errorObj(E_3018);
        }

        //从数据库获取密码，用时间戳加密，与password进行对比
        String md5str = Base64.getEncoder().encodeToString(DigestUtils.md5Digest((user.getPassword() + timestamp).getBytes(StandardCharsets.UTF_8)));
        if (!password.equals(md5str)) {
            return RESTRetUtils.errorObj(E_3011);
        }

        Subject subject = SecurityUtils.getSubject();
        String token = tokenUtil.generateToken(userName, timestamp);
        TokenModel tokenModel = new TokenModel();
        tokenModel.setToken(token);
        tokenModel.setSource(LOGIN_SOURCE);
//        tokenUtil.tokenMap.put(token,tokenModel);
        JwtToken loginJwt = JwtToken.builder().token(token).ip(remote).build();
        try {
            subject.login(loginJwt);
            Map<String, Object> map = new HashMap<>();
            map.put("token", token);

            //判断用户是否过期
            if (user.getExpiration_time() == null || user.getExpiration_time().before(new Date())) {
                map.put("expire", true);
                return RESTRetUtils.successObj(map);
            }
            map.put("expire", false);
            return RESTRetUtils.successObj(map);
        } catch (AuthenticationException ex) {
            if (ex.getMessage().equals("Account has been deactivated!")) {
                return RESTRetUtils.errorObj(E_3013);
            } else if (ex.getMessage().equals("Token is expired!")) {
                return RESTRetUtils.errorObj(E_3014);
            } else if (ex.getMessage().equals("access ip is inconsistent with user ip!")){
                return RESTRetUtils.errorObj(E_3018);
            }
            return RESTRetUtils.errorObj(E_3002);
        }
    }

    /**
     * @return RESTRetBase
     * @Title: edgeInfo
     * @Description:
     */
    @GetMapping(value = "/auth/info")  //获取登录用户信息
    public RESTRetBase edgeInfo(HttpServletRequest httpServletRequest, @RequestHeader("Authorization") String token) {

        String username = tokenUtil.getUsernameFromToken(token);
//        User user1 = (User) SecurityUtils.getSubject().getPrincipal();

        String remote = getRemoteIP(httpServletRequest);


        if (username != null) {
            User user = userDao.getUserByUserName(username);
            if(user == null){
                return RESTRetUtils.errorObj(E_3011);
            }
            List<String> roleNames= userDao.getRoleNamesByUsername(user.getUser_name());
            user.setRoleNames(roleNames);
            user.setUser_ip(remote);
            return RESTRetUtils.successObj(user);
        }
        return RESTRetUtils.errorObj(E_3011);
    }

    /**
     * @return RESTRetBase
     * @Title: getUserPermissions
     * @Description: 获取用户的权限
     */
    @GetMapping(value = "/auth/user/{username}/permissions")
    public RESTRetBase getUserPermissions(@PathVariable String username) {

        if (username != null) {
            return RESTRetUtils.successObj(permissionDao.getPermissionsByUserName(username));
        }
        return RESTRetUtils.errorObj(E_3011);
    }


    /**
     * @return RESTRetBase
     * @Title: edgeLogout
     * @Description:
     */
    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @GetMapping(value = "/auth/logout")  //登出
    public RESTRetBase edgeLogout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return RESTRetUtils.successObj("登出成功！");
    }

    /**
     * @param pageNum pageNum
     * @param pageRow pageRow
     * @return RESTRetBase
     * @Title: getUsers
     * @Description:
     */
//    @RequiresPermissions({"sys:auth:user:view"})  //获取所有用户信息
    @GetMapping(value = "/auth/user")
    public RESTRetBase getUsers(@RequestParam(required = false) Integer pageNum,
                                @RequestParam(required = false) Integer pageRow) throws JsonProcessingException {

        //不分页获取
        if (pageNum == null || pageRow == null) {
            List<User> users = userDao.findAllUser();
            for (User user : users) {
                List<String> rolenames = userDao.getRoleNamesByUsername(user.getUser_name());
                user.setRoleNames(rolenames);
            }
            return RESTRetUtils.successObj(users);
        }

        //分页获取
//        Sort sort = new Sort(Sort.Direction.ASC, "user_name");
//        Pageable pageable = new PageRequest(pageNum, pageRow, sort); //分页设置
        Pageable pageable = PageRequest.of(pageNum, pageRow); //分页设置

        Page<User> users = userDao.findAll(pageable);
        for (User user : users) {
            List<String> rolenames = userDao.getRoleNamesByUsername(user.getUser_name());
            user.setRoleNames(rolenames);
        }
        return RESTRetUtils.successObj(users);
    }

    /**
     * @param userName userName
     * @return RESTRetBase
     * @Title: getSingleUser
     * @Description:
     */
//    @RequiresPermissions({"sys:auth:user:view"})  //获取单个用户信息
    @GetMapping(value = "/auth/user/{userName}")
    public RESTRetBase getSingleUser(@PathVariable String userName) {
        User user = userDao.getUserByUserName(userName);
        if (user == null) {
            return RESTRetUtils.errorObj(E_3011);
        }
        List<String> rolenames = userDao.getRoleNamesByUsername(user.getUser_name());
        user.setRoleNames(rolenames);
        return RESTRetUtils.successObj(user);
    }


    /**
     * @param joinUser joinUser
     * @return RESTRetBase
     * @Title: addUser
     * @Description:
     */
    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    @PostMapping(value = "/auth/user")
    public RESTRetBase addUser(@RequestBody User joinUser) {

//        if (joinUser.getPassword() == null) {
//            return RESTRetUtils.errorObj(E_3005);
//        }
        // 没有指定组织机构，就设置为null
        if (!StringUtils.hasLength(joinUser.getOrganization())) {
            joinUser.setOrganization(null);
        }
        // 数据库中Ext_infos字段不为空，处理前端传的空串
        if (!StringUtils.hasLength(joinUser.getExt_infos())) {
            joinUser.setExt_infos("{}");
        }

        if (!CollectionUtils.isEmpty(joinUser.getRoleNames())) {
            if (joinUser.getRoleNames().contains("superadmin")) {
                return RESTRetUtils.errorObj(false,E_3021);
            }
        }
        String userName = joinUser.getUser_name();
        String dbPassword = joinUser.getPassword();
        joinUser.setPassword(dbPassword);
        if (userDao.getUserByUserName(joinUser.getUser_name()) != null) {
            return RESTRetUtils.errorObj(E_3003);
        }
        userDao.save(joinUser);
        List<String> roleNames = joinUser.getRoleNames();
        if (roleNames != null) {
            for (String name : roleNames) {
                Role role = roleDao.getRoleByUserName(name);
                UserRole userRole = new UserRole(joinUser, role);
                userRoleDao.save(userRole);
            }
        }

        return RESTRetUtils.successObj();
    }

//    /**
//     * @return RESTRetBase
//     * @Title: addUser
//     * @Description:
//     */
//    @RequiresPermissions({"sys:auth:user:modify"})  //重置密码
//    @PutMapping(value = "/auth/user/reset/{userName}")
//    public RESTRetBase resetUser(@PathVariable String userName) {
//        User user = userDao.getUserByUserName(userName);
//        String dbPassword = Base64.getEncoder().encodeToString(DigestUtils.md5(userName + initialPassword));
//        user.setPassword(dbPassword);
//        user.setExpiration_time(new Date());
//        userDao.save(user);
//        return RESTRetUtils.successObj();
//    }

    /**
     * @param
     * @param userName userName
     * @return RESTRetBase
     * @Title: updateUserInfo
     * @Description:
     */
    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    @PutMapping(value = "/auth/user/{userName}")
    public RESTRetBase updateUserInfo(@PathVariable String userName, @RequestBody JsonObject jsonObject) {

        Set<String> set = jsonObject.keySet();
        User olduser = userDao.getUserByUserName(userName);
        if (set.contains("expiration_time") && !jsonObject.get("expiration_time").isJsonNull()) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(STANDARD_DATE_FORMAT_UTC);
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
            Date expirationTime = null;
            try {
                expirationTime = simpleDateFormat.parse(jsonObject.get("expiration_time").getAsString());
                olduser.setExpiration_time(expirationTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
//        if (set.contains("expiration_time") && jsonObject.get("expiration_time").isJsonNull()) {
//            olduser.setExpiration_time(null);
//        }
        if (set.contains("user_name")) {
            String modiUserName = jsonObject.get("user_name").getAsString();
            if (userDao.getUserByUserName(modiUserName) != null) {
                return RESTRetUtils.errorObj(E_3003);
            }
            olduser.setUser_name(modiUserName);
        }
        if (set.contains("status")) {
            olduser.setStatus(jsonObject.get("status").getAsShort());
        }
        if (set.contains("password")) {
            olduser.setPassword(jsonObject.get("password").getAsString());
        }
        if (set.contains("nick_name")) {
            olduser.setNick_name(jsonObject.get("nick_name").getAsString());
        }
        if (set.contains("mobile_phone")) {
            olduser.setMobile_phone(jsonObject.get("mobile_phone").getAsString());
        }
        if (set.contains("email")) {
            olduser.setEmail(jsonObject.get("email").getAsString());
        }
        if (set.contains("organization")) {
            olduser.setOrganization(jsonObject.get("organization").getAsString());
        }
        //登陆ip限制
        if (set.contains("login_ip_limit")) {
            olduser.setLogin_ip_limit(jsonObject.get("login_ip_limit").getAsString());
        }
        if (set.contains("roleNames")) {
            //先查看该用户用否有超级管理远角色，如果有不允许修改
            List<String> currentUserRoleNames = userDao.getRoleNamesByUsername(olduser.getUser_name());
            if (currentUserRoleNames.contains("superadmin")) {
                return RESTRetUtils.errorObj(E_3010);
            }

            //先清空用户原来的角色
            List<UserRole> userRoles = userRoleDao.findByUser(olduser);

            //如果userRoles的长度不为0，表示用户已有角色，需要先清空
            if (userRoles.size() != 0) {
                for (UserRole userRole : userRoles) {
                    userRoleDao.delete(userRole);
                }
            }
            Gson gson = new Gson();
            List<String> roleNames = gson.fromJson(jsonObject.get("roleNames"), List.class);
            if (!CollectionUtils.isEmpty(roleNames)) {
                if (roleNames.contains("superadmin")) {
                    return RESTRetUtils.errorObj(E_3021);
                }
            }
            for (String name : roleNames) {
                Role role = roleDao.getRoleByUserName(name);
                UserRole userRole = new UserRole(olduser, role);
                userRoleDao.save(userRole);
            }
        }
        userDao.save(olduser);
        List<String> rolenames = userDao.getRoleNamesByUsername(olduser.getUser_name());
        olduser.setRoleNames(rolenames);
        return RESTRetUtils.successObj(olduser);
    }

    /**
     * @param userName userName
     * @return RESTRetBase
     * @Title: deleteUser
     * @Description:
     */
    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    @DeleteMapping(value = "/auth/user/{userName}")
    public RESTRetBase deleteUser(@PathVariable String userName) {
        User olduser = userDao.getUserByUserName(userName);
        if (olduser == null) {
            return RESTRetUtils.errorObj(E_3011);
        }
        // 根据用户名查询该用户的角色
        List<String> userRoleList = userDao.getRoleNamesByUsername(olduser.getUser_name());
        // 如果是超级管理员，则不能被删除
        if (!CollectionUtils.isEmpty(userRoleList)){
            if (userRoleList.contains("superadmin")){
                return RESTRetUtils.errorObj(E_3010);
            }
        }

        //先从UserRole表中删除用户权限
        List<UserRole> userRoles = userRoleDao.findByUser(olduser);
        if (userRoles != null) {
            for (UserRole userRole : userRoles) {
                userRoleDao.delete(userRole);
            }
        }
        userDao.delete(olduser);
        return RESTRetUtils.successObj();
    }

    /**
     * @param jsonObject
     * @return RESTRetBase
     * @Title: updatePassword
     * @Description:
     */
    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @PostMapping(value = "/auth/password")    //修改密码
    public RESTRetBase updatePassword(@RequestBody JsonObject jsonObject) {
        //获取登录用户
        User subject = (User) SecurityUtils.getSubject().getPrincipal();
        String old_password = jsonObject.get("old_password").getAsString();
        String new_password = jsonObject.get("new_password").getAsString();

        // 空值验证
        if (jsonObject.get("old_password") == null || !StringUtils.hasLength(jsonObject.get("old_password").getAsString())) {
            return RESTRetUtils.errorObj(E_3006);
        }
        if (jsonObject.get("new_password") == null || !StringUtils.hasLength(jsonObject.get("new_password").getAsString())) {
            return RESTRetUtils.errorObj(E_3005);
        }

        if (!subject.getPassword().equals(old_password)) {
            return RESTRetUtils.errorObj(E_3006);
        }
        // 旧密码和新密码相同
        if (old_password.equals(new_password)) {
            return RESTRetUtils.errorObj(E_3004);
        }
        subject.setPassword(new_password);
        if (!subject.getUser_name().equals("admin")) {
            subject.setExpiration_time(getHalfYearLaterDate());
        }
        userDao.save(subject);
        return RESTRetUtils.successObj();
    }

    //获得半年后的日期
    public Date getHalfYearLaterDate() {
        LocalDate localDate = LocalDate.now().plus(6, ChronoUnit.MONTHS);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * @param roles    roles
     * @param userName userName
     * @return RESTRetBase
     * @Title: updateUserRole
     * @Description:
     */
    @SysLog(collector = WebOperationCollector.class,extractor = WebOperationRecordExtractor.class)
    @RequiresRoles(value = {"admin","superadmin"},logical = Logical.OR)
    @PutMapping(value = "/auth/user/{userName}/roles")   //修改用户的所有角色
    public RESTRetBase updateUserRole(@PathVariable String userName, @RequestBody List<Role> roles) {
        User user = userDao.getUserByUserName(userName);
        List<UserRole> userRoles = userRoleDao.findByUser(user);

        //如果userRoles的长度为0，表示该用户还未拥有任何角色，此接口为给用户增加角色
        if (userRoles.size() == 0) {
            for (Role role : roles) {
                UserRole userRole = new UserRole(user, role);
                userRoleDao.save(userRole);
            }
            return RESTRetUtils.successObj();
        }

        //否则先清空再增加角色
        for (UserRole userRole : userRoles) {
            userRoleDao.delete(userRole);
        }
        for (Role role : roles) {
            UserRole userRole = new UserRole(user, role);
            userRoleDao.save(userRole);
        }
        return RESTRetUtils.successObj();
    }

    /**
     * @param userName userName
     * @return RESTRetBase
     * @Title: getUserRole
     * @Description:
     */
//    @RequiresPermissions({"sys:auth:user:view"})
    @GetMapping(value = "/auth/user/{userName}/roles")    //获取用户的所有角色
    public RESTRetBase getUserRole(@PathVariable String userName) {
        User user = userDao.getUserByUserName(userName);
        if (user == null) {
            return RESTRetUtils.errorObj(E_3011);
        }
        List<UserRole> userRoles = userRoleDao.findByUser(user);
        List<Role> roles = new ArrayList<>();
        for (UserRole userRole : userRoles) {
            roles.add(userRole.getRole());
        }
        return RESTRetUtils.successObj(roles);
    }

    /**
     * 鉴权（供itsstudio网关调用）
     * @return todo
     */
    @GetMapping("/auth/user/ispermitted")
    public RESTRet<Boolean> isPermitted(){

        return RESTRetUtils.successObj(true);
    }

    /**
     * 认证（供itsstudio网关调用）
     * @return
     */
    @GetMapping("/auth/user/isauthenticated")
    public RESTRet<Boolean> isAuthenticated(){
        // 程序运行到此处时，前面已经对token进行了验证
        return RESTRetUtils.successObj(true);
    }

    @GetMapping("/auth/user/modifystatus")
    public RESTRet isModifyInitPassword(){
//        String initPassword = "pmq7VoTEWWLYh1ZPCDRujQ==";
        String initPassword = Base64.getEncoder().encodeToString(DigestUtils.md5Digest("admin123456".getBytes()));
        String password = userDao.getUserByUserName("admin").getPassword();

        JsonObject res = new JsonObject();
        res.addProperty("isModify",!initPassword.equals(password));
        res.addProperty("langType",agentLangType);

        return RESTRetUtils.successObj(res);
    }

    /**
     * 该接口只限定于修改初始化管理员密码使用
     * @param jsonObject
     * @return
     */
    @PostMapping("/auth/user/modifypassword")
    public RESTRetBase modifyAdminPassword(@RequestBody JsonObject jsonObject) {
        // 空值校验
        if (jsonObject.get("new_password") == null || jsonObject.get("new_password").getAsString().isEmpty()) {
            return RESTRetUtils.errorObj(E_3005);
        }

        // 管理员初始密码
        String init_password = Base64.getEncoder().encodeToString(DigestUtils.md5Digest("admin123456".getBytes()));
        // 如果数据库中保存的非初始密码，接口调用失败
        String password = userDao.getUserByUserName("admin").getPassword();
        if (!init_password.equals(password)) {
            return RESTRetUtils.errorObj(E_3006);
        }
        // 获取新密码
        String new_password = jsonObject.get("new_password").getAsString();
        // 旧密码和新密码相同
        if (init_password.equals(new_password)) {
            return RESTRetUtils.errorObj(E_3004);
        }

        int row = userDao.updateAdminPassword(new_password);
        return RESTRetUtils.successObj(row == 1);
    }


    public String getRemoteIP(HttpServletRequest request) {
//        if (request.getHeader("x-forwarded-for") == null) {
//            return request.getRemoteAddr();
//        }
//        return request.getHeader("x-forwarded-for");
        // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");

            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");

            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");

            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");

            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = ips[index];
                if (! ("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

    public static String md5(String text, String key) throws Exception {
        //加密后的字符串
        String encodeStr = DigestUtils.md5DigestAsHex((text + key).getBytes());
        return encodeStr;
    }

    /**
     * Token ip校验，如果ip与数据库中不一致，则拒绝访问
     * 只需要在用户登录的时候判断一次
     * @param
     * @return
     */
    // todo: 增加正则匹配
    public boolean checkip(String remoteip, String userip ) {

        if (userip.equals("*") ) return true;
        if (userip.equals(".*") ) return true;
        if (userip.equals(remoteip)) return true;
        if (userip.equals("")) return true;
        return false;
    }
}
